﻿using Cinch;
using FR.SAFTAnalyser.Model;
using FR.SAFTAnalyser.Services;
using FR.SAFTAnalyser.ViewModels.Pane;
using MEFedMVVM.Common;
using System.IO;

namespace FR.SAFTAnalyser.ViewModels
{
    public class SaftViewModel : DocumentPartViewModel
    {
        IOpenFileService openFileService;

        public SaftViewModel()
            : base("SAF-T")
        {
            this.openFileService = ServiceResolver.Instance.OpenFileService;
            Init();
        }

        private void Init()
        {
            SaftFileName = "Por favor, coloque aqui o ficheiro SAFT.";
            PublicKeyFileName = "Por favor, coloque aqui o ficheiro com a chave pública.";
            PrivateKeyFileName = "Por favor, coloque aqui o ficheiro com a chave privada.";
            StockFileName = "Por favor, coloque aqui o ficheiro das existências (xml ou csv).";

            NotifyPropertyChanged(ObservableHelper.CreateArgs<SaftViewModel>(x => x.SaftFileName));
            NotifyPropertyChanged(ObservableHelper.CreateArgs<SaftViewModel>(x => x.PublicKeyFileName));
            NotifyPropertyChanged(ObservableHelper.CreateArgs<SaftViewModel>(x => x.StockFileName));

            if (!Designer.IsInDesignMode)
            {
                //events
                Mediator.Instance.Register(this);

                //Commands
                DoValidateHashCommand = new SimpleCommand<object, object>(CanValidateHash, ValidateHash);
                DoValidateHashMGCommand = new SimpleCommand<object, object>(CanValidateHashMG, ValidateHashMG);
                DoValidateHashWDCommand = new SimpleCommand<object, object>(CanValidateHashWD, ValidateHashWD);

                DoValidateSchemaCommand = new SimpleCommand<object, object>(CanValidateSchema, ValidateSchema);
                DoValidateSchemaV1Command = new SimpleCommand<object, object>(CanValidateSchema, ValidateV1Schema);
                DoValidateSchemaV2Command = new SimpleCommand<object, object>(CanValidateSchema, ValidateV2Schema);
                DoValidateSchemaV3Command = new SimpleCommand<object, object>(CanValidateSchema, ValidateV3Schema);

                OpenSaftFileCommand = new SimpleCommand<object, object>(CanOpenSaftFile, OpenSaftFile);
                OpenPublicKeyFileCommand = new SimpleCommand<object, object>(CanOpenPublicKeyFile, OpenPublicKeyFile);
                OpenPrivateKeyFileCommand = new SimpleCommand<object, object>(CanOpenPrivateKeyFile, OpenPrivateKeyFile);
                OpenStockFileCommand = new SimpleCommand<object, object>(CanOpenStockFile, OpenStockFile);

                GenerateHashCommand = new SimpleCommand<object, object>(CanGenerateHash, GenerateHash);
                GenerateHashMGCommand = new SimpleCommand<object, object>(CanGenerateHashMG, GenerateHashMG);
                GenerateHashWDCommand = new SimpleCommand<object, object>(CanGenerateHashWD, GenerateHashWD);
            }
        }

        #region Message mediator
        [MediatorMessageSink(MessageType.OPEN_SAFT_FILE)]
        private void OpenSaftFile(string filename)
        {
            if (File.Exists(filename))
                this.SaftFileName = filename;
        }
        [MediatorMessageSink(MessageType.OPEN_PUBLIC_KEY_FILE)]
        private void OpenPublicKeyFile(string filename)
        {
            if (File.Exists(filename))
                this.PublicKeyFileName = filename;
        }
        [MediatorMessageSink(MessageType.OPEN_PRIVATE_KEY_FILE)]
        private void OpenPrivateKeyFile(string filename)
        {
            if (File.Exists(filename))
                this.PrivateKeyFileName = filename;
        }
        [MediatorMessageSink(MessageType.OPEN_STOCK_FILE)]
        private void OpenStockFile(string filename)
        {
            if (File.Exists(filename))
                this.StockFileName = filename;
        }
        #endregion Message mediator

        string saftFileName;
        public string SaftFileName
        {
            get
            {
                if (Workspace.Workspace.Instance.Config.RememberLastOpenFiles && File.Exists(Workspace.Workspace.Instance.Config.SAFTFileName) && saftFileName.Equals(Workspace.Workspace.Instance.Config.SAFTFileName, System.StringComparison.OrdinalIgnoreCase) == false)
                {
                    saftFileName = Workspace.Workspace.Instance.Config.SAFTFileName;
                    Workspace.Workspace.Instance.OpenSaftFile(saftFileName);
                }

                return saftFileName;
            }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    saftFileName = value;

                    if (saftFileName.IndexOf(Workspace.Workspace.Instance.FicheiroSAFT, System.StringComparison.OrdinalIgnoreCase) < 0)
                        Workspace.Workspace.Instance.OpenSaftFile(saftFileName);

                    NotifyPropertyChanged(ObservableHelper.CreateArgs<SaftViewModel>(x => x.SaftFileName));
                }
            }
        }

        string publicKeyFileName;
        public string PublicKeyFileName
        {
            get
            {
                if (Workspace.Workspace.Instance.Config.RememberLastOpenFiles && File.Exists(Workspace.Workspace.Instance.Config.PublicKeyFileName) && string.Equals(Workspace.Workspace.Instance.Config.PublicKeyFileName, publicKeyFileName, System.StringComparison.OrdinalIgnoreCase) == false)
                {
                    publicKeyFileName = Workspace.Workspace.Instance.Config.PublicKeyFileName;
                    Workspace.Workspace.Instance.OpenPublicKeyFile(publicKeyFileName);
                }

                return publicKeyFileName;
            }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    publicKeyFileName = value;

                    if (File.Exists(publicKeyFileName) && (string.IsNullOrEmpty(SAFT.SaftAnalyser.Instance.PublicKeyFileName) || publicKeyFileName.IndexOf(SAFT.SaftAnalyser.Instance.PublicKeyFileName, System.StringComparison.OrdinalIgnoreCase) < 0))
                        Workspace.Workspace.Instance.OpenPublicKeyFile(publicKeyFileName);

                    NotifyPropertyChanged(ObservableHelper.CreateArgs<SaftViewModel>(x => x.PublicKeyFileName));
                }
            }
        }

        string privateKeyFileName;
        public string PrivateKeyFileName
        {
            get
            {
                if (Workspace.Workspace.Instance.Config.RememberLastOpenFiles && File.Exists(Workspace.Workspace.Instance.Config.PrivateKeyFileName) && string.Equals(Workspace.Workspace.Instance.Config.PrivateKeyFileName, privateKeyFileName, System.StringComparison.OrdinalIgnoreCase) == false)
                {
                    privateKeyFileName = Workspace.Workspace.Instance.Config.PrivateKeyFileName;
                    SAFT.SaftAnalyser.Instance.PrivateKeyFileName = privateKeyFileName;
                }

                return privateKeyFileName;
            }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    privateKeyFileName = value;

                    if (File.Exists(privateKeyFileName) && (string.IsNullOrEmpty(SAFT.SaftAnalyser.Instance.PrivateKeyFileName) || privateKeyFileName.IndexOf(SAFT.SaftAnalyser.Instance.PrivateKeyFileName, System.StringComparison.OrdinalIgnoreCase) < 0))
                        Workspace.Workspace.Instance.OpenPrivateKeyFile(privateKeyFileName);

                    NotifyPropertyChanged(ObservableHelper.CreateArgs<SaftViewModel>(x => x.PrivateKeyFileName));
                }
            }
        }

        string stockFileName;
        public string StockFileName
        {
            get
            {
                if (Workspace.Workspace.Instance.Config.RememberLastOpenFiles && File.Exists(Workspace.Workspace.Instance.Config.StockFileName) && stockFileName.Equals(Workspace.Workspace.Instance.Config.StockFileName, System.StringComparison.OrdinalIgnoreCase) == false)
                {
                    stockFileName = Workspace.Workspace.Instance.Config.StockFileName;
                    Workspace.Workspace.Instance.OpenStockFile(stockFileName);
                }

                return stockFileName;
            }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    stockFileName = value;

                    if (stockFileName.IndexOf(Workspace.Workspace.Instance.FicheiroSTOCK, System.StringComparison.OrdinalIgnoreCase) < 0)
                        Workspace.Workspace.Instance.OpenStockFile(stockFileName);

                    NotifyPropertyChanged(ObservableHelper.CreateArgs<SaftViewModel>(x => x.StockFileName));
                }
            }
        }
        #region Commands
        public SimpleCommand<object, object> DoValidateHashCommand { get; private set; }
        public SimpleCommand<object, object> DoValidateHashWDCommand { get; set; }
        public SimpleCommand<object, object> DoValidateHashMGCommand { get; set; }
        private void ValidateHash(object args)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.ValidateHash();
        }
        private bool CanValidateHash(object args)
        {
            return (File.Exists(this.SaftFileName) && File.Exists(this.PublicKeyFileName) && SAFT.SaftAnalyser.Instance.SaftFile != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments.SalesInvoices != null);
        }
        private void ValidateHashWD(object obj)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.ValidateHashWD();
        }
        private bool CanValidateHashWD(object arg)
        {
            return (File.Exists(this.SaftFileName) && File.Exists(this.PublicKeyFileName) && SAFT.SaftAnalyser.Instance.SaftFile != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments.WorkingDocuments != null);
        }
        private void ValidateHashMG(object obj)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.ValidateHashMG();
        }
        private bool CanValidateHashMG(object arg)
        {
            return (File.Exists(this.SaftFileName) && File.Exists(this.PublicKeyFileName) && SAFT.SaftAnalyser.Instance.SaftFile != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments.MovementOfGoods != null);
        }

        public SimpleCommand<object, object> DoValidateSchemaCommand { get; private set; }
        public SimpleCommand<object, object> DoValidateSchemaV1Command { get; set; }
        public SimpleCommand<object, object> DoValidateSchemaV2Command { get; set; }
        public SimpleCommand<object, object> DoValidateSchemaV3Command { get; set; }
        private void ValidateV3Schema(object obj)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.ValidateSchema(SaftFileVersion.V10301);
        }
        private void ValidateV2Schema(object obj)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.ValidateSchema(SaftFileVersion.V10201);
        }
        private void ValidateV1Schema(object obj)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.ValidateSchema(SaftFileVersion.V10101);
        }
        private void ValidateSchema(object args)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.ValidateSchema();
        }
        private bool CanValidateSchema(object args)
        {
            return File.Exists(this.SaftFileName);
        }

        public SimpleCommand<object, object> OpenSaftFileCommand { get; private set; }
        private void OpenSaftFile(object args)
        {
            if (openFileService != null)
            {
                openFileService.FileName = "";
                this.SaftFileName = openFileService.OpenFile("SAFT (*.xml)|*.xml");
            }
        }
        private bool CanOpenSaftFile(object args)
        {
            return true;
        }

        public SimpleCommand<object, object> OpenPublicKeyFileCommand { get; private set; }
        private void OpenPublicKeyFile(object args)
        {
            if (openFileService != null)
            {
                openFileService.FileName = "";
                this.PublicKeyFileName = openFileService.OpenFile("Chave pública (.txt, .pem) | *.txt;*.pem");
            }
        }
        private bool CanOpenPublicKeyFile(object args)
        {
            return true;
        }

        public SimpleCommand<object, object> OpenPrivateKeyFileCommand { get; private set; }
        private void OpenPrivateKeyFile(object args)
        {
            if (openFileService != null)
            {
                openFileService.FileName = "";

                this.PrivateKeyFileName = openFileService.OpenFile("Chave privada (.txt, .pem) | *.txt;*.pem");
            }
        }
        private bool CanOpenPrivateKeyFile(object args)
        {
            return true;
        }

        public SimpleCommand<object, object> OpenStockFileCommand { get; private set; }
        private void OpenStockFile(object args)
        {
            if (openFileService != null)
            {
                openFileService.FileName = "";
                this.StockFileName = openFileService.OpenFile("Ficheiro Xml (*.xml)|*.xml|Csv (*.csv)|*.csv");
            }
        }
        private bool CanOpenStockFile(object args)
        {
            return true;
        }

        public SimpleCommand<object, object> GenerateHashCommand { get; private set; }
        public SimpleCommand<object, object> GenerateHashWDCommand { get; set; }
        public SimpleCommand<object, object> GenerateHashMGCommand { get; set; }
        private void GenerateHash(object args)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.GenerateInvoiceHash();
        }
        private bool CanGenerateHash(object args)
        {
            return (File.Exists(this.PrivateKeyFileName) && SAFT.SaftAnalyser.Instance.SaftFile != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments.SalesInvoices != null);
        }
        private void GenerateHashWD(object obj)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.GenerateHashWD();
        }
        private bool CanGenerateHashWD(object arg)
        {
            return (File.Exists(this.SaftFileName) && File.Exists(this.PrivateKeyFileName) && SAFT.SaftAnalyser.Instance.SaftFile != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments.WorkingDocuments != null);
        }
        private void GenerateHashMG(object obj)
        {
            SAFTAnalyser.SAFT.SaftAnalyser.Instance.GenerateHashMG();
        }
        private bool CanGenerateHashMG(object arg)
        {
            return (File.Exists(this.SaftFileName) && File.Exists(this.PrivateKeyFileName) && SAFT.SaftAnalyser.Instance.SaftFile != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments != null && SAFT.SaftAnalyser.Instance.SaftFile.SourceDocuments.MovementOfGoods != null);
        }
        #endregion Commands
    }
}
